/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.tom.social.analyzer.analysis;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.SortedTermVectorMapper;
import org.apache.lucene.index.TermVectorEntry;
import org.apache.lucene.index.TermVectorEntryFreqSortedComparator;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.getopt.stempel.lucene.StempelAnalyzer;
import pl.tom.social.analyzer.common.Results;
import pl.tom.social.analyzer.analysis.SocialAnalyzer;
import pl.tom.social.common.sitetool.ISiteTools;
import pl.tom.social.common.sitetool.SiteToolsFactory;
import pl.tom.social.dal.entity.Site;
import pl.tom.social.dal.entity.SiteEntry;
import pl.tom.social.dal.utils.EntryIterator;

/**
 *
 * @author Tom
 */
public class TermFreqCounter {

	private static final Logger logger = Logger.getLogger(TermFreqCounter.class);
	Site site;
	boolean save = false;

	public TermFreqCounter(Site site, boolean save) {
		this.site = site;
		this.save = save;
	}

	public TermFreqCounter(Site site) {
		this(site, false);
	}

	public Map<String, Integer> get(int limit) {
		ISiteTools tools = SiteToolsFactory.getTools(site);
		Directory dir = null;
		try {
			dir = FSDirectory.getDirectory("luceneDir");
		} catch (IOException ex) {
			logger.log(Level.ERROR, ex);
		}
		createDocument(dir, site, tools);
		Map<String, Integer> result = createMap(dir, limit);
		if (save) {
			//TODO finish this
		}

		return result;
	}

	private Map<String, Integer> createMap(Directory dir, int limit) {
		Map<String, Integer> result = new HashMap<String, Integer>();
		IndexReader reader = null;
		try {
			reader = IndexReader.open(dir);
			SortedTermVectorMapper mapper = new SortedTermVectorMapper(new TermVectorEntryFreqSortedComparator());
			reader.getTermFreqVector(0, mapper);
			SortedSet s = mapper.getTermVectorEntrySet();
			for (Iterator iter = s.iterator(); iter.hasNext();) {
				TermVectorEntry entry = (TermVectorEntry) iter.next();
				result.put(entry.getTerm(), entry.getFrequency());
				if (result.size() == limit) {
					break;
				}
			}
		} catch (CorruptIndexException ex) {
			logger.log(Level.ERROR, ex);
		} catch (IOException ex) {
			logger.log(Level.ERROR, ex);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (CorruptIndexException ex) {
					logger.log(Level.ERROR, ex);
				} catch (IOException ex) {
					logger.log(Level.ERROR, ex);
				}
			}
		}
		return result;
	}

	private void createDocument(Directory dir, Site site, ISiteTools tools) {
		Document doc = null;
		IndexWriter writer = null;
		try {
			StempelAnalyzer analyzer = new StempelAnalyzer();
			writer = new IndexWriter(dir, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
			doc = new Document();
			for (Iterator iter = new EntryIterator(site); iter.hasNext();) {
				SiteEntry entry = (SiteEntry) iter.next();
				String body = tools.getHtmlAsText(entry.getBody());
				doc.add(new Field("body", body, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES));
			}
			writer.addDocument(doc);
		} catch (CorruptIndexException ex) {
			logger.log(Level.ERROR, ex);
		} catch (LockObtainFailedException ex) {
			logger.log(Level.ERROR, ex);
		} catch (IOException ex) {
			logger.log(Level.ERROR, ex);
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (CorruptIndexException ex) {
					logger.log(Level.ERROR, ex);
				} catch (IOException ex) {
					logger.log(Level.ERROR, ex);
				}
			}
		}
	}
//	private void storeResults(Site site, Map<String, Integer> result) {
//		SocialDatabaseFacade db = new SocialDatabaseFacade();
//		Analysis a = new Analysis(new Date(), AnalysisType.TermFreq.ordinal());
//		a.getSiteList().add(site);
//		db.persistEntity(a);
//		for(String term : result.keySet()) {
//			TermResult tr = null;
//			try {
//				tr = db.getTermResult(term);
//				if(term == null) {
//					tr = new TermResult(term);
//					db.persistEntity(tr);
//				}
//				AnalysisTermResult atr = new AnalysisTermResult(new AnalysisTermResultPK(a.getId(), tr.getId()),
//						result.get(term));
//				db.persistEntity(atr);
//			} catch(Exception ex) {
//				logger.log(Level.ERROR, ex);
//			}
//
//		}
//	}
}
